package com.cgc.venus.server.job.service;

import com.cgc.venus.server.core.exception.VenusException;
import com.cgc.venus.server.core.k8s.inter.K8sManageService;
import com.cgc.venus.server.core.utils.DateUtil;
import com.cgc.venus.server.job.bean.AppManageBean;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentStatus;
import io.fabric8.kubernetes.api.model.apps.StatefulSet;
import io.fabric8.kubernetes.api.model.apps.StatefulSetStatus;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AppStatsServiceImpl {
    private static final Logger logger = LogManager.getLogger(AppStatsServiceImpl.class);
    public static final String Kind_Deployment = "kind: Deployment";
    public static final String Kind_StatefulSet = "kind: StatefulSet";
    public static final String APP_STATUS_RUNNING = "运行中";
    public static final String APP_STATUS_RUNNING_MESSAGE = "应用正常运行中";
    public static final String APP_STATUS_CLOSE = "已关闭";
    public static final String APP_STATUS_CLOSE_MESSAGE = "应用已经关闭,没有实例运行";
    public static final String APP_STATUS_ERROR = "异常";
    public static final String APP_STATUS_ERROR_MESSAGE = "应用异常,一个或多个容器出错,请到管理页面查看详情";
    public static final String APP_STATUS_CREATEING = "创建中...";
    public static final String APP_STATUS_CREATEING_MESSAGE = "";

    @Autowired
    private K8sManageService k8sManageService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
    }

    public String getDeploymentReplicas(String namespace,String appNameKube) throws VenusException {
        Deployment deployment = k8sManageService.getDeployment(namespace,appNameKube);
        DeploymentStatus deploymentStatus = deployment.getStatus();
        // 总的副本数
        int totalR = 0;
        try {
            totalR = deployment.getSpec().getReplicas().intValue();
        } catch (NullPointerException nn) {
            totalR = 0;
        }
        // 可用的副本数
        int readyR = 0;
        try {
            readyR = deploymentStatus.getReadyReplicas();
        } catch (NullPointerException n) {
            readyR = 0;
        }
        return readyR + "/" + totalR;
    }

    public String getStatefulSetReplicas(String namespace,String appNameKube) throws VenusException {
        StatefulSet statefulSet = k8sManageService.getStatefulSet(namespace,appNameKube);
        StatefulSetStatus statefulSetStatus = statefulSet.getStatus();
        // 总的副本数
        int totalR = 0;
        try {
            totalR = statefulSet.getSpec().getReplicas().intValue();
        } catch (NullPointerException nn) {
            totalR = 0;
        }
        // 可用的副本数
        int readyR = 0;
        try {
            readyR = statefulSetStatus.getReadyReplicas().intValue();
        } catch (NullPointerException n) {
            readyR = 0;
        }
        return readyR + "/" + totalR;
    }

    /*
    * 根据应用类型,获得应用实例数
    * */
    public String getReplicasByKind(String appKind, String namespace, String appNameKube) throws VenusException {
        String replicas = "";
        if (Kind_Deployment.indexOf(appKind) != -1) {
            replicas = getDeploymentReplicas(namespace, appNameKube);
        } else if (Kind_StatefulSet.indexOf(appKind) != -1) {
            replicas = getStatefulSetReplicas(namespace,appNameKube);
        }
        return replicas;
    }

    public String getAppStatus(String replicas,String createTime) throws VenusException {
        String[] replicasArr = replicas.split("/");
        int readyR = Integer.valueOf(replicasArr[0]);
        int totalR = Integer.valueOf(replicasArr[1]);
        String status = APP_STATUS_RUNNING;
        if (createTime.indexOf("秒") != -1 && readyR != totalR) {
            status = APP_STATUS_CREATEING;
        } else if (totalR > readyR) {
            status = APP_STATUS_ERROR;
        } else if (readyR == 0 && totalR == 0) {
            status = APP_STATUS_CLOSE;
        }
        return status;
    }

    public List<AppManageBean> queryAllAppInfo()throws VenusException{
        String sql = "SELECT  " +
                "id, app_name AS appName," +
                " app_name_kube AS appNameKube, " +
                "app_kind AS appKind, " +
                "image_name AS imageName, " +
                "image_version AS " +
                "imageVersion, " +
                "described, " +
                "namespace," +
                "create_time  AS createTime, " +
                "last_update_time AS lastUpdateTime " +
                "FROM  t_app_manage ORDER BY create_time DESC";
        List<AppManageBean> maps = new ArrayList<AppManageBean>();
        try{
            maps = jdbcTemplate.query(sql, new RowMapper<AppManageBean>() {
                public AppManageBean mapRow(ResultSet rs, int rowNum) throws SQLException {
                    try {
                        return getAppBean(rs);
                    } catch (VenusException e) {
                        logger.error(e.getMessage(), e);
                    }
                    return null;
                }
            });
        }catch (EmptyResultDataAccessException ex){
            return maps;
        }
        return maps;
    }
    private AppManageBean getAppBean(ResultSet rs ) throws SQLException, VenusException {
        AppManageBean appManageBean = new AppManageBean();
        appManageBean.setId(rs.getString("id"));
        appManageBean.setAppName(rs.getString("appName"));
        appManageBean.setAppNameKube(rs.getString("appNameKube"));
        appManageBean.setAppKind(rs.getString("appKind"));
        appManageBean.setImageName(rs.getString("imageName"));
        appManageBean.setImageVersion(rs.getString("imageVersion"));
        appManageBean.setDescribed(rs.getString("described"));
        appManageBean.setNamespace(rs.getString("namespace"));
        Timestamp fromDateStamp = rs.getTimestamp("createTime");
        // 时间差
        String fromDate = DateUtil.TimeStamp2Date(fromDateStamp, DateUtil.yyyy_MM_dd_HH_mm_ss);
        String toDate = DateUtil.getCurrentTime(DateUtil.yyyy_MM_dd_HH_mm_ss);
        String timeDiff = DateUtil.getTimeDifference(DateUtil.yyyy_MM_dd_HH_mm_ss,fromDate,toDate);
        appManageBean.setCreateTime(fromDate);
        appManageBean.setTimeDiff(timeDiff);
        Timestamp lastUpdateTime = rs.getTimestamp("lastUpdateTime");
        appManageBean.setLastUpdateTime(DateUtil.TimeStamp2Date(lastUpdateTime,DateUtil.yyyy_MM_dd_HH_mm_ss));
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        appManageBean.setToday(sdf.format(new Date()).equals(sdf.format(fromDateStamp)));
        String replicas = getReplicasByKind(appManageBean.getAppKind(),appManageBean.getNamespace(),appManageBean.getAppNameKube());
        String status = getAppStatus(replicas,appManageBean.getTimeDiff());
        appManageBean.setStatus(status);
        appManageBean.setReplicas(replicas);
        return appManageBean;
    }
}